InĀ [1]:
import numpy as np
from vivarium import Vivarium
from spatio_flux import PROCESS_DICT, TYPES_DICT, build_path, render_path

Make the initial Vivarium¶

view available types and processes

InĀ [2]:
# TODO -- make a spatio-flux specific Vivarium with the the core preloaded
vi = Vivarium(processes=PROCESS_DICT, types=TYPES_DICT)
InĀ [3]:
# view the available types
vi.get_types()
Out[3]:
['',
 'length^2*mass/current^2*time^2',
 'length^2*mass/current*time^2',
 'length^3/mass*time^2',
 'current^2*time^3/length^2*mass',
 'mass/current*time^2',
 'array',
 'enum',
 'current*time',
 'union',
 'mass^0_5/length^1_5',
 'current^2*time^4/length^2*mass',
 'length^2/time^2',
 'positive_float',
 'composite',
 'length/mass',
 'mass^0_5/length^0_5*time',
 'length^2*mass/temperature*time^2',
 'length^2',
 'list',
 'length*temperature',
 'current*length*time',
 'mass/length*time^2',
 'length*mass/current^2*time^2',
 'substance',
 'current*length^2*time',
 'current*time/substance',
 'wires',
 '/temperature*time',
 'particle',
 'reaction',
 'printing_unit',
 'current^2*time^4/length^3*mass',
 'boolean',
 '/printing_unit',
 'mass',
 'luminosity',
 'mass/length^3',
 'temperature',
 'length^4*mass/time^3',
 'path',
 'length^2*mass/current*time^3',
 'length^1_5*mass^0_5/time',
 'boundary_side',
 'length*mass/time^2',
 'current',
 'maybe',
 'schema',
 'current*time/mass',
 'length^3',
 'kinetics',
 'step',
 'luminosity/length^2',
 'length^4*mass/current*time^3',
 'tree',
 'length^1_5*mass^0_5/time^2',
 'length/time^2',
 'interval',
 '/length',
 'length^2*mass/current^2*time^3',
 'time/length',
 'emitter_mode',
 'string',
 'current*length^2',
 'number',
 'mass/time^3',
 'length^0_5*mass^0_5',
 '/substance',
 'map',
 'time',
 'protocol',
 'length*mass/current*time^3',
 'length^3*mass/current^2*time^4',
 'substance/time',
 'mass/length*time',
 'substance/length^3',
 'time^2/length',
 'length/time',
 'length*time/mass',
 'length^0_5*mass^0_5/time',
 'any',
 '/time',
 'edge',
 'length',
 'process',
 'bounds',
 'length^2*mass/time^2',
 'mass/temperature^4*time^3',
 'length^2*mass/time',
 'length^3/time',
 'integer',
 'float',
 'printing_unit/length',
 'length^2*mass/substance*temperature*time^2',
 'length^2*mass/time^3',
 'tuple',
 'length^2/time',
 'mass/length',
 'current*time^2/length^2*mass',
 'quote',
 'mass/time^2',
 'substrate_role']
InĀ [4]:
# view the available processes
vi.get_processes()
Out[4]:
['composite',
 'DiffusionAdvection',
 'Particles',
 'console-emitter',
 'MinimalParticle',
 'DynamicFBA',
 'json-emitter',
 'ram-emitter']

dFBA¶

Dynamic Flux Balance Analysis (dFBA) extends traditional Flux Balance Analysis (FBA) to model the dynamic behavior of metabolic networks over time, allowing for the simulation of growth and substrate consumption in a changing environment.

InĀ [5]:
# inspect the config schema for the 'increase' process
vi.process_config('DynamicFBA')
Out[5]:
{'model_file': 'string',
 'kinetic_params': 'map[tuple[float,float]]',
 'substrate_update_reactions': 'map[string]',
 'biomass_identifier': 'string',
 'bounds': 'map[bounds]'}
InĀ [6]:
dfba_config  = vi.process_config('DynamicFBA', dataclass=True)  # TODO -- make this work
Error finding process DynamicFBA: 'type_parameters'
InĀ [7]:
# TODO - enable get_dataclass to work with the new process
# dfba_config  = v.get_dataclass('DynamicFBA')
dfba_config = {
    "model_file": "textbook",
    "kinetic_params": {
        "glucose": (0.5, 1),
        "acetate": (0.5, 2)},
    "substrate_update_reactions": {
        "glucose": "EX_glc__D_e",
        "acetate": "EX_ac_e"},
    "biomass_identifier": "biomass",
    "bounds": {
        "EX_o2_e": {"lower": -2, "upper": None},
        "ATPM": {"lower": 1, "upper": 1}
    }
}
InĀ [8]:
# make the vivarium
v = Vivarium(processes=PROCESS_DICT, types=TYPES_DICT)

# add a dynamic FBA process called 'dFBA'
v.add_process(name="dFBA",
              process_id="DynamicFBA",
              config=dfba_config,
              )
v.diagram(dpi='70')
Out[8]:
No description has been provided for this image
InĀ [9]:
mol_ids = ["glucose", "acetate", "biomass"]
path=["fields"]

for mol_id in mol_ids:
    v.add_object(
        name=mol_id,
        path=path,
        value=np.random.rand()
    )

v.connect_process(
    process_name="dFBA",
    inputs={
            "substrates": {
                mol_id: build_path(path, mol_id)
                for mol_id in mol_ids}
        },
    outputs={
            "substrates": {
                mol_id: build_path(path, mol_id)
                for mol_id in mol_ids}
        }
)

# add an emitter to save results
v.add_emitter()

# TODO -- show_values does not work
v.diagram(dpi='70', show_values=True)
Out[9]:
No description has been provided for this image
InĀ [10]:
v.set_value(path = ['fields', 'glucose'], value=10)
v.set_value(path = ['fields', 'biomass'], value=0.1)
field = v.get_value(['fields'])
print(field)
{'glucose': 10, 'acetate': 0.7037378681382127, 'biomass': 0.1}
InĀ [11]:
# run the simulation for 10 time units
v.run(interval=60)
InĀ [12]:
v.plot_timeseries(
    subplot_size=(8, 3),
    combined_vars=[
        [
            '/fields/glucose',
            '/fields/acetate',
            '/fields/biomass'
        ]
    ]
)
Out[12]:
No description has been provided for this image

Spatial dFBA¶

InĀ [13]:
mol_ids = ["glucose", "acetate", "biomass"]
path=["fields"]
rows = 2
columns = 1

# make the vivarium
v2 = Vivarium(processes=PROCESS_DICT, types=TYPES_DICT)
for mol_id in mol_ids:
    v2.add_object(
        name=mol_id,
        path=path,
        value=np.random.rand(rows, columns)
    )

# add a dynamic FBA process at every location
for i in range(rows):
    for j in range(columns):
        dfba_name = f"dFBA[{i},{j}]"
        path_name = build_path(path, 'mol_id', i, j)
        print(f'Adding {dfba_name} to {path_name}\n')

        # add a process for this location
        v2.add_process(
            name=dfba_name,
            process_id="DynamicFBA",
            config=dfba_config,
        )
        v2.connect_process(
            process_name=dfba_name,
            inputs={"substrates": {
                        mol_id: build_path(path, mol_id, i, j)
                        for mol_id in mol_ids}},
            outputs={"substrates": {
                        mol_id: build_path(path, mol_id, i, j)
                        for mol_id in mol_ids}}
        )

# add an emitter to save results
v2.add_emitter()

v2.diagram(dpi='70')
Adding dFBA[0,0] to ['fields', 'mol_id', 0, 0]

Adding dFBA[1,0] to ['fields', 'mol_id', 1, 0]

Out[13]:
No description has been provided for this image
InĀ [14]:
v2
Out[14]:
Vivarium( 
{ 'dFBA[0,0]': { 'address': 'local:DynamicFBA',
                 'config': { 'biomass_identifier': 'biomass',
                             'bounds': { 'ATPM': {'lower': 1.0, 'upper': 1.0},
                                         'EX_o2_e': { 'lower': -2.0,
                                                      'upper': None}},
                             'kinetic_params': { 'acetate': (0.5, 2.0),
                                                 'glucose': (0.5, 1.0)},
                             'model_file': 'textbook',
                             'substrate_update_reactions': { 'acetate': 'EX_ac_e',
                                                             'glucose': 'EX_glc__D_e'}},
                 'inputs': { 'substrates': { 'acetate': [ 'fields',
                                                          'acetate',
                                                          0,
                                                          0],
                                             'biomass': [ 'fields',
                                                          'biomass',
                                                          0,
                                                          0],
                                             'glucose': [ 'fields',
                                                          'glucose',
                                                          0,
                                                          0]}},
                 'instance': <spatio_flux.processes.dfba.DynamicFBA object at 0x12803fa10>,
                 'interval': 1.0,
                 'outputs': { 'substrates': { 'acetate': [ 'fields',
                                                           'acetate',
                                                           0,
                                                           0],
                                              'biomass': [ 'fields',
                                                           'biomass',
                                                           0,
                                                           0],
                                              'glucose': [ 'fields',
                                                           'glucose',
                                                           0,
                                                           0]}},
                 'shared': None},
  'dFBA[1,0]': { 'address': 'local:DynamicFBA',
                 'config': { 'biomass_identifier': 'biomass',
                             'bounds': { 'ATPM': {'lower': 1.0, 'upper': 1.0},
                                         'EX_o2_e': { 'lower': -2.0,
                                                      'upper': None}},
                             'kinetic_params': { 'acetate': (0.5, 2.0),
                                                 'glucose': (0.5, 1.0)},
                             'model_file': 'textbook',
                             'substrate_update_reactions': { 'acetate': 'EX_ac_e',
                                                             'glucose': 'EX_glc__D_e'}},
                 'inputs': { 'substrates': { 'acetate': [ 'fields',
                                                          'acetate',
                                                          1,
                                                          0],
                                             'biomass': [ 'fields',
                                                          'biomass',
                                                          1,
                                                          0],
                                             'glucose': [ 'fields',
                                                          'glucose',
                                                          1,
                                                          0]}},
                 'instance': <spatio_flux.processes.dfba.DynamicFBA object at 0x128068ed0>,
                 'interval': 1.0,
                 'outputs': { 'substrates': { 'acetate': [ 'fields',
                                                           'acetate',
                                                           1,
                                                           0],
                                              'biomass': [ 'fields',
                                                           'biomass',
                                                           1,
                                                           0],
                                              'glucose': [ 'fields',
                                                           'glucose',
                                                           1,
                                                           0]}},
                 'shared': None},
  'emitter': { 'address': 'local:ram-emitter',
               'config': {'emit': {'fields': 'any', 'global_time': 'any'}},
               'inputs': {'fields': ['fields'], 'global_time': ['global_time']},
               'instance': <process_bigraph.emitter.RAMEmitter object at 0x11fbb4ad0>,
               'outputs': None},
  'fields': { 'acetate': array([[0.94243295],
       [0.22249636]]),
              'biomass': array([[0.50279638],
       [0.30531076]]),
              'glucose': array([[0.18712085],
       [0.8048707 ]])},
  'global_time': 0.0})
InĀ [15]:
# change some initial values
v2.set_value(path = ['fields', 'glucose', 0, 0], value=10)
v2.set_value(path = ['fields', 'biomass', 0, 0], value=0.1)
field = v2.get_value(['fields'])
print(field)
{'glucose': array([[10.       ],
       [ 0.8048707]]), 'acetate': array([[0.94243295],
       [0.22249636]]), 'biomass': array([[0.1       ],
       [0.30531076]])}
InĀ [16]:
v2.run(60)
InĀ [17]:
v2.get_timeseries(as_dataframe=True)
Out[17]:
/global_time /fields/glucose /fields/acetate /fields/biomass
0 0.0 [[10.0], [0.8048706975269881]] [[0.9424329478919963], [0.22249635975890014]] [[0.1], [0.3053107553015897]]
1 1.0 [[9.904761904761905], [0.6165488346421795]] [[0.9545410000880855], [0.05491255366842457]] [[0.1079432568708625], [0.3248588221508157]]
2 2.0 [[9.80200585245463], [0.43716453723748616]] [[0.9675168875642264], [0.0]] [[0.11651530697082768], [0.3411210770331022]]
3 3.0 [[9.691145527078628], [0.27803982449204534]] [[0.9814117183137139], [0.0]] [[0.12576552148631978], [0.35397004919062214]]
4 4.0 [[9.571550338512791], [0.15154530936018212]] [[0.99627709547691], [0.0]] [[0.13574706721093277], [0.36376254935005725]]
... ... ... ... ...
56 56.0 [[0.0], [0.02329114629515195]] [[0.0], [0.0]] [[0.9893401479522954], [0.3717590284394552]]
57 57.0 [[0.0], [0.02329114629515195]] [[0.0], [0.0]] [[0.9893401479522954], [0.3717590284394552]]
58 58.0 [[0.0], [0.02329114629515195]] [[0.0], [0.0]] [[0.9893401479522954], [0.3717590284394552]]
59 59.0 [[0.0], [0.02329114629515195]] [[0.0], [0.0]] [[0.9893401479522954], [0.3717590284394552]]
60 60.0 [[0.0], [0.02329114629515195]] [[0.0], [0.0]] [[0.9893401479522954], [0.3717590284394552]]

61 rows Ɨ 4 columns

InĀ [18]:
# get a list of all the paths so they can be plotted together in a single graph
all_paths = []
for i in range(rows):
    for j in range(columns):
        # get the paths for this location
        location_path = []
        for mol_id in mol_ids:
            this_path = build_path(path, mol_id, i, j)
            rendered_path = render_path(this_path)
            location_path.append(rendered_path)
        all_paths.append(location_path)
print(all_paths)
[['/fields/glucose/0/0', '/fields/acetate/0/0', '/fields/biomass/0/0'], ['/fields/glucose/1/0', '/fields/acetate/1/0', '/fields/biomass/1/0']]
InĀ [19]:
v2.plot_timeseries(
    subplot_size=(8, 3),
    combined_vars=all_paths
)
Out[19]:
No description has been provided for this image
InĀ [20]:
v2.show_video()

Diffusion/Advection¶

This approach models the physical processes of diffusion and advection in two dimensions, providing a way to simulate how substances spread and are transported across a spatial domain, essential for understanding patterns of concentration over time and space.

InĀ [21]:
bounds = (10.0, 10.0)
n_bins = (10, 10)
mol_ids = [
    'glucose',
    'acetate',
    'biomass'
]
diffusion_rate = 1e-1
diffusion_dt = 1e-1
advection_coeffs = {
    'biomass': (0, -0.1)
}
path = ['fields']

v3 = Vivarium(processes=PROCESS_DICT, types=TYPES_DICT)

for mol_id in mol_ids:
    v3.add_object(
        name=mol_id,
        path=path,
        value=np.random.rand(n_bins[0], n_bins[1])
    )

v3.add_process(name='diffusion_advection',
               process_id='DiffusionAdvection',
               config={
                   'n_bins': n_bins,
                   'bounds': bounds,
                   'default_diffusion_rate': diffusion_rate,
                   'default_diffusion_dt': diffusion_dt,
                   # 'diffusion_coeffs': diffusion_coeffs_all,
                   'advection_coeffs': advection_coeffs,
               },
               inputs={'fields': ['fields']},
               outputs={'fields': ['fields']}
               )

# add an emitter to save results
v3.add_emitter()

v3.diagram(dpi='70')
Out[21]:
No description has been provided for this image
InĀ [22]:
v3.run(60)
InĀ [23]:
v3.plot_snapshots(n_snapshots=5)
No description has been provided for this image
InĀ [24]:
v3.show_video()

COMETS (Computation Of Microbial Ecosystems in Time and Space)¶

COMETS combines dynamic FBA with spatially resolved physical processes (like diffusion and advection) to simulate the growth, metabolism, and interaction of microbial communities within a structured two-dimensional environment, capturing both biological and physical complexities.

InĀ [25]:
bounds = (10.0, 10.0)
n_bins = (10, 10)
mol_ids = [
    'glucose',
    'acetate',
    'biomass'
]
diffusion_rate = 1e-1
diffusion_dt = 1e-1
advection_coeffs = {
    'biomass': (0, -0.1)
}
path = ['fields']

v4 = Vivarium(processes=PROCESS_DICT, types=TYPES_DICT)

# create the molecular fields
# for mol_id in mol_ids:
v4.add_object(
    name='glucose',
    path=path,
    value=np.random.rand(n_bins[0], n_bins[1])
)
v4.add_object(
    name='biomass',
    path=path,
    value=np.ones((n_bins[0], n_bins[1])) * 0.01
)
v4.add_object(
    name='acetate',
    path=path,
    value=np.zeros((n_bins[0], n_bins[1]))
)


# add a diffusion/advection process
v4.add_process(name='diffusion_advection',
               process_id='DiffusionAdvection',
               config={
                   'n_bins': n_bins,
                   'bounds': bounds,
                   'default_diffusion_rate': diffusion_rate,
                   'default_diffusion_dt': diffusion_dt,
                   'advection_coeffs': advection_coeffs},
               inputs={'fields': ['fields']},
               outputs={'fields': ['fields']}
               )

# add a dynamic FBA process at every location
for i in range(n_bins[0]):
    for j in range(n_bins[1]):
        dfba_name = f"dFBA[{i},{j}]"
        path_name = build_path(path, 'mol_id', i, j)
        print(f'Adding {dfba_name} to {path_name}\n')

        # add a process for this location
        v4.add_process(
            name=dfba_name,
            process_id="DynamicFBA",
            config=dfba_config,
        )
        v4.connect_process(
            process_name=dfba_name,
            inputs={"substrates": {
                        mol_id: build_path(path, mol_id, i, j)
                        for mol_id in mol_ids}},
            outputs={"substrates": {
                        mol_id: build_path(path, mol_id, i, j)
                        for mol_id in mol_ids}}
        )

# add an emitter to save results
v4.add_emitter()

v4.diagram(dpi='70')
Adding dFBA[0,0] to ['fields', 'mol_id', 0, 0]

Adding dFBA[0,1] to ['fields', 'mol_id', 0, 1]

Adding dFBA[0,2] to ['fields', 'mol_id', 0, 2]

Adding dFBA[0,3] to ['fields', 'mol_id', 0, 3]

Adding dFBA[0,4] to ['fields', 'mol_id', 0, 4]

Adding dFBA[0,5] to ['fields', 'mol_id', 0, 5]

Adding dFBA[0,6] to ['fields', 'mol_id', 0, 6]

Adding dFBA[0,7] to ['fields', 'mol_id', 0, 7]

Adding dFBA[0,8] to ['fields', 'mol_id', 0, 8]

Adding dFBA[0,9] to ['fields', 'mol_id', 0, 9]

Adding dFBA[1,0] to ['fields', 'mol_id', 1, 0]

Adding dFBA[1,1] to ['fields', 'mol_id', 1, 1]

Adding dFBA[1,2] to ['fields', 'mol_id', 1, 2]

Adding dFBA[1,3] to ['fields', 'mol_id', 1, 3]

Adding dFBA[1,4] to ['fields', 'mol_id', 1, 4]

Adding dFBA[1,5] to ['fields', 'mol_id', 1, 5]

Adding dFBA[1,6] to ['fields', 'mol_id', 1, 6]

Adding dFBA[1,7] to ['fields', 'mol_id', 1, 7]

Adding dFBA[1,8] to ['fields', 'mol_id', 1, 8]

Adding dFBA[1,9] to ['fields', 'mol_id', 1, 9]

Adding dFBA[2,0] to ['fields', 'mol_id', 2, 0]

Adding dFBA[2,1] to ['fields', 'mol_id', 2, 1]

Adding dFBA[2,2] to ['fields', 'mol_id', 2, 2]

Adding dFBA[2,3] to ['fields', 'mol_id', 2, 3]

Adding dFBA[2,4] to ['fields', 'mol_id', 2, 4]

Adding dFBA[2,5] to ['fields', 'mol_id', 2, 5]

Adding dFBA[2,6] to ['fields', 'mol_id', 2, 6]

Adding dFBA[2,7] to ['fields', 'mol_id', 2, 7]

Adding dFBA[2,8] to ['fields', 'mol_id', 2, 8]

Adding dFBA[2,9] to ['fields', 'mol_id', 2, 9]

Adding dFBA[3,0] to ['fields', 'mol_id', 3, 0]

Adding dFBA[3,1] to ['fields', 'mol_id', 3, 1]

Adding dFBA[3,2] to ['fields', 'mol_id', 3, 2]

Adding dFBA[3,3] to ['fields', 'mol_id', 3, 3]

Adding dFBA[3,4] to ['fields', 'mol_id', 3, 4]

Adding dFBA[3,5] to ['fields', 'mol_id', 3, 5]

Adding dFBA[3,6] to ['fields', 'mol_id', 3, 6]

Adding dFBA[3,7] to ['fields', 'mol_id', 3, 7]

Adding dFBA[3,8] to ['fields', 'mol_id', 3, 8]

Adding dFBA[3,9] to ['fields', 'mol_id', 3, 9]

Adding dFBA[4,0] to ['fields', 'mol_id', 4, 0]

Adding dFBA[4,1] to ['fields', 'mol_id', 4, 1]

Adding dFBA[4,2] to ['fields', 'mol_id', 4, 2]

Adding dFBA[4,3] to ['fields', 'mol_id', 4, 3]

Adding dFBA[4,4] to ['fields', 'mol_id', 4, 4]

Adding dFBA[4,5] to ['fields', 'mol_id', 4, 5]

Adding dFBA[4,6] to ['fields', 'mol_id', 4, 6]

Adding dFBA[4,7] to ['fields', 'mol_id', 4, 7]

Adding dFBA[4,8] to ['fields', 'mol_id', 4, 8]

Adding dFBA[4,9] to ['fields', 'mol_id', 4, 9]

Adding dFBA[5,0] to ['fields', 'mol_id', 5, 0]

Adding dFBA[5,1] to ['fields', 'mol_id', 5, 1]

Adding dFBA[5,2] to ['fields', 'mol_id', 5, 2]

Adding dFBA[5,3] to ['fields', 'mol_id', 5, 3]

Adding dFBA[5,4] to ['fields', 'mol_id', 5, 4]

Adding dFBA[5,5] to ['fields', 'mol_id', 5, 5]

Adding dFBA[5,6] to ['fields', 'mol_id', 5, 6]

Adding dFBA[5,7] to ['fields', 'mol_id', 5, 7]

Adding dFBA[5,8] to ['fields', 'mol_id', 5, 8]

Adding dFBA[5,9] to ['fields', 'mol_id', 5, 9]

Adding dFBA[6,0] to ['fields', 'mol_id', 6, 0]

Adding dFBA[6,1] to ['fields', 'mol_id', 6, 1]

Adding dFBA[6,2] to ['fields', 'mol_id', 6, 2]

Adding dFBA[6,3] to ['fields', 'mol_id', 6, 3]

Adding dFBA[6,4] to ['fields', 'mol_id', 6, 4]

Adding dFBA[6,5] to ['fields', 'mol_id', 6, 5]

Adding dFBA[6,6] to ['fields', 'mol_id', 6, 6]

Adding dFBA[6,7] to ['fields', 'mol_id', 6, 7]

Adding dFBA[6,8] to ['fields', 'mol_id', 6, 8]

Adding dFBA[6,9] to ['fields', 'mol_id', 6, 9]

Adding dFBA[7,0] to ['fields', 'mol_id', 7, 0]

Adding dFBA[7,1] to ['fields', 'mol_id', 7, 1]

Adding dFBA[7,2] to ['fields', 'mol_id', 7, 2]

Adding dFBA[7,3] to ['fields', 'mol_id', 7, 3]

Adding dFBA[7,4] to ['fields', 'mol_id', 7, 4]

Adding dFBA[7,5] to ['fields', 'mol_id', 7, 5]

Adding dFBA[7,6] to ['fields', 'mol_id', 7, 6]

Adding dFBA[7,7] to ['fields', 'mol_id', 7, 7]

Adding dFBA[7,8] to ['fields', 'mol_id', 7, 8]

Adding dFBA[7,9] to ['fields', 'mol_id', 7, 9]

Adding dFBA[8,0] to ['fields', 'mol_id', 8, 0]

Adding dFBA[8,1] to ['fields', 'mol_id', 8, 1]

Adding dFBA[8,2] to ['fields', 'mol_id', 8, 2]

Adding dFBA[8,3] to ['fields', 'mol_id', 8, 3]

Adding dFBA[8,4] to ['fields', 'mol_id', 8, 4]

Adding dFBA[8,5] to ['fields', 'mol_id', 8, 5]

Adding dFBA[8,6] to ['fields', 'mol_id', 8, 6]

Adding dFBA[8,7] to ['fields', 'mol_id', 8, 7]

Adding dFBA[8,8] to ['fields', 'mol_id', 8, 8]

Adding dFBA[8,9] to ['fields', 'mol_id', 8, 9]

Adding dFBA[9,0] to ['fields', 'mol_id', 9, 0]

Adding dFBA[9,1] to ['fields', 'mol_id', 9, 1]

Adding dFBA[9,2] to ['fields', 'mol_id', 9, 2]

Adding dFBA[9,3] to ['fields', 'mol_id', 9, 3]

Adding dFBA[9,4] to ['fields', 'mol_id', 9, 4]

Adding dFBA[9,5] to ['fields', 'mol_id', 9, 5]

Adding dFBA[9,6] to ['fields', 'mol_id', 9, 6]

Adding dFBA[9,7] to ['fields', 'mol_id', 9, 7]

Adding dFBA[9,8] to ['fields', 'mol_id', 9, 8]

Adding dFBA[9,9] to ['fields', 'mol_id', 9, 9]

Out[25]:
No description has been provided for this image
InĀ [26]:
v4.run(60)
InĀ [27]:
v4.plot_snapshots(n_snapshots=5)
No description has been provided for this image
InĀ [28]:
v4.show_video()
InĀ [29]:
v4.plot_timeseries(
    subplot_size=(8, 3),
    query=[
        '/fields/glucose/0/0',
        '/fields/acetate/0/0',
        '/fields/biomass/0/0',
        '/global_time',
    ]
)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[29], line 1
----> 1 v4.plot_timeseries(
      2     subplot_size=(8, 3),
      3     query=[
      4         '/fields/glucose/0/0',
      5         '/fields/acetate/0/0',
      6         '/fields/biomass/0/0',
      7         'global_time',
      8     ]
      9 )

File ~/code/vivarium-interface/vivarium/vivarium.py:664, in Vivarium.plot_timeseries(self, query, significant_digits, subplot_size, ncols, combined_vars)
    646 def plot_timeseries(self,
    647                     query=None,
    648                     significant_digits=None,
   (...)
    651                     combined_vars=None
    652                     ):
    653     """
    654     Plots the timeseries data for all variables using matplotlib.
    655     Each variable (or group of variables) gets its own subplot.
   (...)
    662         combined_vars (list of lists, optional): Lists of variables to combine into the same subplot. Default is None.
    663     """
--> 664     timeseries = self.get_timeseries(query=query, significant_digits=significant_digits)
    665     timeseries = flatten_timeseries_to_scalar_paths(timeseries)
    667     # Extract time vector

File ~/code/vivarium-interface/vivarium/vivarium.py:615, in Vivarium.get_timeseries(self, query, significant_digits, as_dataframe)
    606 def get_timeseries(self,
    607                    query=None,
    608                    significant_digits=None,
    609                    as_dataframe=False,
    610                    ):
    611     """
    612     Gets the results and converts them to timeseries format
    613     """
--> 615     emitter_results = self.get_results(query=query,
    616                                        significant_digits=significant_digits)
    618     def append_to_timeseries(timeseries, state, path=()):
    619         if isinstance(state, dict):

File ~/code/vivarium-interface/vivarium/vivarium.py:602, in Vivarium.get_results(self, query, significant_digits)
    600     if "emitter" in path:
    601         emitter = get_path(self.composite.state, path)
--> 602         results.extend(emitter['instance'].query(query))
    604 return round_floats(results, significant_digits=significant_digits)

File ~/code/process-bigraph/process_bigraph/emitter.py:248, in RAMEmitter.query(self, query)
    246 result = {}
    247 for path in query:
--> 248     element = get_path(t, path)
    249     result = set_path(result, path, element)
    250 results.append(result)

File ~/code/bigraph-schema/bigraph_schema/utilities.py:200, in get_path(tree, path)
    198     return None
    199 else:
--> 200     return get_path(tree[head], path[1:])

File ~/code/bigraph-schema/bigraph_schema/utilities.py:200, in get_path(tree, path)
    198     return None
    199 else:
--> 200     return get_path(tree[head], path[1:])

File ~/code/bigraph-schema/bigraph_schema/utilities.py:197, in get_path(tree, path)
    195 else:
    196     head = path[0]
--> 197     if not tree or head not in tree:
    198         return None
    199     else:

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()